/* SPDX-License-Identifier: BSD-2-Clause */
/*******************************************************************************
 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
 * All rights reserved.
 ******************************************************************************/
#ifndef IFAPI_POLICY_TYPES_H
#define IFAPI_POLICY_TYPES_H

#include <stdint.h>           // for uint8_t

#include "fapi_types.h"       // for UINT8_ARY
#include "tss2_common.h"      // for UINT32, INT32, UINT16
#include "tss2_tpm2_types.h"  // for TPM2B_DIGEST, TPM2B_NAME, TPM2B_NONCE

struct TPML_POLICYELEMENTS;

typedef UINT32 TPMI_POLICYTYPE;
#define POLICYELEMENTS                 0
#define POLICYOR                       1    /**< None */
#define POLICYSIGNED                   2    /**< None */
#define POLICYSECRET                   3    /**< None */
#define POLICYPCR                      4    /**< None */
#define POLICYLOCALITY                 5    /**< None */
#define POLICYNV                       6    /**< None */
#define POLICYCOUNTERTIMER             7    /**< None */
#define POLICYCOMMANDCODE              8    /**< None */
#define POLICYPHYSICALPRESENCE         9    /**< None */
#define POLICYCPHASH                   10    /**< None */
#define POLICYNAMEHASH                 11    /**< None */
#define POLICYDUPLICATIONSELECT        12    /**< None */
#define POLICYAUTHORIZE                13    /**< None */
#define POLICYAUTHVALUE                14    /**< None */
#define POLICYPASSWORD                 15    /**< None */
#define POLICYNVWRITTEN                16    /**< None */
#define POLICYTEMPLATE                 17    /**< None */
#define POLICYAUTHORIZENV              18    /**< None */
#define POLICYACTION                   19    /**< None */

/** Policy type TPMS_POLICYSIGNED
 */
typedef struct {
    TPM2B_NONCE                                nonceTPM;    /**< This is a value returned by TPM2_StartAuthSession and thus n */
    TPM2B_DIGEST                                cpHashA;    /**< This value will be automatically generated by the FAPI. */
    TPM2B_NONCE                               policyRef;    /**< Default is zero-length */
    INT32                                    expiration;    /**< This value will be -1 by the FAPI */
    TPMT_SIGNATURE                                 auth;    /**< This value is generated from at runtime via a callback. */
    TPM2B_NAME                                publicKey;    /**< This will be automatically generated from keyPath, keyPublic */
    char                                 *publicKeyHint;    /**< A human readable hint to denote which public key to use. */
    char                                       *keyPath;    /**< A reference to a key inside the FAPI keystore */
    TPMT_PUBLIC                               keyPublic;    /**< None */
    char                                        *keyPEM;    /**< <p>The TPM2B_NAME is constructed with a TPMT_PUBLIC from this */
    TPMI_ALG_HASH                         keyPEMhashAlg;    /**< (optional) Default = SHA256 */
    TPMT_RSA_SCHEME                           rsaScheme;    /**< (optional) Default = TPM2_ALG_RSAPSS */
    TPMT_SIGNATURE                        signature_tpm;
} TPMS_POLICYSIGNED;

/** Policy type TPMS_POLICYSECRET
 */
typedef struct {
    TPM2B_NONCE                                nonceTPM;    /**< None */
    TPM2B_DIGEST                                cpHashA;    /**< None */
    TPM2B_NONCE                               policyRef;    /**< Default is zero length */
    INT32                                    expiration;    /**< None */
    char                                    *objectPath;    /**< Path of the object */
    TPM2B_NAME                               objectName;    /**< Public name of the object */
} TPMS_POLICYSECRET;

/** Policy type TPMS_POLICYLOCALITY
 */
typedef struct {
    TPMA_LOCALITY                              locality;    /**< None */
} TPMS_POLICYLOCALITY;

/** Policy type TPMS_POLICYNV
 */
typedef struct {
    char                                        *nvPath;    /**< None */
    TPMI_RH_NV_INDEX                            nvIndex;    /**< None */
    TPMS_NV_PUBLIC                             nvPublic;    /**< None */
    TPMI_RH_NV_AUTH                          authHandle;    /**< This is determined by FAPI at runtime. */
    TPM2B_OPERAND                              operandB;    /**< None */
    UINT16                                       offset;    /**< Default value is 0 */
    TPM2_EO                                   operation;    /**< Default value is EQUAL */
} TPMS_POLICYNV;

/** Policy type TPMS_POLICYCOUNTERTIMER
 */
typedef struct {
    TPM2B_OPERAND                              operandB;    /**< None */
    UINT16                                       offset;    /**< Default is 0 */
    TPM2_EO                                   operation;    /**< None */
} TPMS_POLICYCOUNTERTIMER;

/** Policy type TPMS_POLICYCOMMANDCODE
 */
typedef struct {
    TPM2_CC                                        code;    /**< None */
} TPMS_POLICYCOMMANDCODE;

/** Policy type TPMS_POLICYPHYSICALPRESENCE
 */
typedef struct {
} TPMS_POLICYPHYSICALPRESENCE;

/** Policy type TPMS_POLICYCPHASH
 */
typedef struct {
    TPM2B_DIGEST                                 cpHash;    /**< None */
} TPMS_POLICYCPHASH;

/** Policy type TPMS_POLICYNAMEHASH
 */
typedef struct {
    UINT32                                          count;    /**< Computed during instantiation */
    UINT32                                              i;    /**< Temporary index for policy calculation */
    TPM2B_NAME                             objectNames[3];    /**< computed during instantiation (if not initialized) */
    char                                    *namePaths[3];    /**< Paths of objects used for retrieving the names */
    TPM2B_DIGEST                                 nameHash;    /**< computed during policy calculation */
} TPMS_POLICYNAMEHASH;

/** Policy type TPMS_POLICYDUPLICATIONSELECT
 */
typedef struct {
    TPM2B_NAME                               objectName;    /**< Will not be used (see includeObject) */
    TPM2B_NAME                            newParentName;    /**< Automatically calculated */
    TPMI_YES_NO                           includeObject;    /**< Always NO */
    char                                 *newParentPath;    /**< None */
    TPMT_PUBLIC                         newParentPublic;    /**< None */
} TPMS_POLICYDUPLICATIONSELECT;

/** Policy type TPMS_POLICYAUTHORIZATION
 */
typedef struct {
    char                                          *type;    /**< tpm */
    TPMT_PUBLIC                                     key;    /**< Selector of the algorithm used for the signature and the pub */
    TPM2B_NONCE                               policyRef;    /**< None */
    TPMT_SIGNATURE                            signature;    /**< None */
    TPMI_ALG_HASH                               hashAlg;
    UINT8_ARY                              pemSignature;
    char                                        *keyPEM;
    TPMT_RSA_SCHEME                           rsaScheme;
} TPMS_POLICYAUTHORIZATION;

typedef struct policy_object_node POLICY_OBJECT;

/** Policy type TPMS_POLICYAUTHORIZE
 */
typedef struct {
    TPM2B_DIGEST                         approvedPolicy;    /**< None */
    TPM2B_NONCE                               policyRef;    /**< None */
    TPM2B_NAME                                  keyName;    /**< Not exposed in JSON, but generated from keyPath, keyPublic o */
    TPMT_TK_VERIFIED                        checkTicket;    /**< None */
    char                                       *keyPath;    /**< A reference to a key inside the FAPI keystore */
    TPMT_PUBLIC                               keyPublic;    /**< None */
    char                                        *keyPEM;    /**< <p> everyone in favour<br /> The TPM2B_NAME is constructed w */
    TPMI_ALG_HASH                         keyPEMhashAlg;    /**< (optional) Default = SHA256 */
    TPMT_RSA_SCHEME                           rsaScheme;    /**< (optional) Default = TPM2_ALG_RSAPSS */
    TPMT_SIGNATURE                            signature;
} TPMS_POLICYAUTHORIZE;

/** Policy type TPMS_POLICYAUTHVALUE
 */
typedef struct {
} TPMS_POLICYAUTHVALUE;

/** Policy type TPMS_POLICYPASSWORD
 */
typedef struct {
} TPMS_POLICYPASSWORD;

/** Policy type TPMS_POLICYNVWRITTEN
 */
typedef struct {
    TPMI_YES_NO                              writtenSet;    /**< Default is yes */
} TPMS_POLICYNVWRITTEN;

/** Policy type TPMS_POLICYTEMPLATE
 */
typedef struct {
    TPM2B_DIGEST                           templateHash;    /**< None */
    TPM2B_PUBLIC                         templatePublic;    /**< None */
} TPMS_POLICYTEMPLATE;

/** Policy type TPMS_POLICYAUTHORIZENV
 */
typedef struct {
    char                                        *nvPath;    /**< None */
    TPMS_NV_PUBLIC                             nvPublic;    /**< None */
    TPM2B_DIGEST                                 policy;    /**< Policy Digest */
    TPMT_HA                                   nv_policy;    /**< Policy stored in NV ram */
    uint8_t                               *policy_buffer;
} TPMS_POLICYAUTHORIZENV;

/** Policy type TPMS_POLICYACTION
 */
typedef struct {
    char                                        *action;    /**< The FAPI will return a string representation of the JSON sub */
} TPMS_POLICYACTION;

/** Policy type TPMS_POLICYPCR
 */
typedef struct {
    struct TPML_PCRVALUES                         *pcrs;    /**< None */
    TPMS_PCR_SELECT                         currentPCRs;    /**< The hashAlg are inferred from */
    TPML_PCR_SELECTION               currentPCRandBanks;    /**< Complete selection with banks  */
} TPMS_POLICYPCR;

/** Policy type TPML_POLICYAUTHORIZATIONS
 */
typedef struct TPML_POLICYAUTHORIZATIONS {
    UINT32                                        count;    /**< None */
    TPMS_POLICYAUTHORIZATION             authorizations[];    /**< Array of policy elements */
} TPML_POLICYAUTHORIZATIONS;

typedef struct TPML_POLICYELEMENTS TPML_POLICYELEMENTS;

/** Policy type TPMS_POLICYBRANCH
 */
typedef struct {
    char                                          *name;    /**< None */
    char                                   *description;    /**< None */
    TPML_DIGEST_VALUES                    policyDigests;
    struct TPML_POLICYELEMENTS                   *policy;    /**< Array of policy elements */
} TPMS_POLICYBRANCH;

/** Policy type TPML_POLICYBRANCHES
 */
typedef struct TPML_POLICYBRANCHES {
    UINT32                                        count;    /**< None */
    TPMS_POLICYBRANCH                    authorizations[];    /**< Array of policy elements */
} TPML_POLICYBRANCHES;

/** Policy type TPMS_POLICYOR
 */
typedef struct {
    struct TPML_POLICYBRANCHES                 *branches;    /**< An (infinite) array of policy elements. This does not contai */
} TPMS_POLICYOR;

/** [u'']
 */
typedef union {
    TPMS_POLICYOR                              PolicyOr;    /**< None */
    TPMS_POLICYSIGNED                      PolicySigned;    /**< None */
    TPMS_POLICYSECRET                      PolicySecret;    /**< None */
    TPMS_POLICYPCR                            PolicyPCR;    /**< None */
    TPMS_POLICYLOCALITY                  PolicyLocality;    /**< None */
    TPMS_POLICYNV                              PolicyNV;    /**< None */
    TPMS_POLICYCOUNTERTIMER          PolicyCounterTimer;    /**< None */
    TPMS_POLICYCOMMANDCODE            PolicyCommandCode;    /**< None */
    TPMS_POLICYPHYSICALPRESENCE    PolicyPhysicalPresence;  /**< None */
    TPMS_POLICYCPHASH                      PolicyCpHash;    /**< None */
    TPMS_POLICYNAMEHASH                  PolicyNameHash;    /**< None */
    TPMS_POLICYDUPLICATIONSELECT   PolicyDuplicationSelect; /**< None */
    TPMS_POLICYAUTHORIZE                PolicyAuthorize;    /**< None */
    TPMS_POLICYAUTHVALUE                PolicyAuthValue;    /**< None */
    TPMS_POLICYPASSWORD                  PolicyPassword;    /**< None */
    TPMS_POLICYNVWRITTEN                PolicyNvWritten;    /**< None */
    TPMS_POLICYTEMPLATE                  PolicyTemplate;    /**< None */
    TPMS_POLICYAUTHORIZENV            PolicyAuthorizeNv;    /**< None */
    TPMS_POLICYACTION                      PolicyAction;    /**< None */
} TPMU_POLICYELEMENT;

/** Policy type TPMT_POLICYELEMENT
 */
typedef struct {
    TPMI_POLICYTYPE                                type;    /**< None */
    TPML_DIGEST_VALUES                    policyDigests;    /**< None */
    TPMU_POLICYELEMENT                          element;    /**< The union does is not embedded inside a field. */
} TPMT_POLICYELEMENT;

/** Policy type TPML_POLICYELEMENTS
 */
struct TPML_POLICYELEMENTS {
    UINT32                                        count;    /**< None */
    TPMT_POLICYELEMENT                         elements[];    /**< Array of policy elements */
};

/** Policy type TPMS_POLICY
 */
typedef struct TPMS_POLICY {
    char                                   *description;    /**< O */
    TPML_DIGEST_VALUES                    policyDigests;    /**< O */
    struct TPML_POLICYAUTHORIZATIONS     *policyAuthorizations;    /**< O */
    struct TPML_POLICYELEMENTS                   *policy;    /**< X */
} TPMS_POLICY;

#endif /* IFAPI_POLICY_TYPES_H */
